package cn.creditease.std;

import cn.creditease.std.enums.JobStatusEnums;
import cn.creditease.std.model.Job;
import cn.creditease.std.producer.Producer;
import cn.creditease.std.utils.IpUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import javax.sql.DataSource;
import lombok.Builder;
import lombok.Data;
import lombok.Getter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

/**
 * @Description: 任务分发者
 * 此对象可以，多个任务分开实例化
 * 只能通过工厂创建
 * @Author: kai.yang
 * @Date: 2019-08-02 14:48
 */
@Builder
@Getter
public class JobAlloter {

    private static final Logger logger = LoggerFactory.getLogger(JobAlloter.class);

    JobAlloter(DataSource dataSource, int maxJobCount, int pageSize, int sum, String jobGroupName, int maxDuration,
        List<Producer> producers) {
        this.dataSource = dataSource;
        this.maxJobCount = maxJobCount;
        this.pageSize = pageSize;
        this.sum = sum;
        this.jobGroupName = jobGroupName;
        this.maxDuration = maxDuration;
        this.producers = producers;
    }

    /**
     * 任务落库数据源
     */
    DataSource dataSource;

    /**
     * 单job最大分配任务数，超过将会报错
     */
    int maxJobCount;

    /**
     * 每个任务处理数据大小
     */
    int pageSize;

    /**
     * 总任务数
     */
    int sum;

    /**
     * job对应组名
     */
    String jobGroupName;

    /**
     * 任务处理最大时长，超过此时间将认为任务意外超时
     */
    int maxDuration;


    /**
     * 配置的通道
     */
    List<Producer> producers;

    /**
     * 开启任务分配的方法
     */
    public void start() {
        List<Job> jobs = new ArrayList<>();
        String localIp = IpUtils.getLocalIp();
        int count = maxJobCount;
        if (sum > maxJobCount) {
            pageSize = (sum - 1) / (maxJobCount - 1);
        } else {
            pageSize = 1;
            count = sum;
        }
        String id = UUID.randomUUID().toString().replace("-","");
        for (int i = 1; i <= maxJobCount; i++) {
            Job job = new Job();
            job.setComsumerId(localIp);
            job.setJobGroupName(jobGroupName);
            job.setJobId(id);
            job.setJobStatus(JobStatusEnums.INIT);
            job.setMaxDuration(maxDuration);
            job.setPageSize(pageSize);
            job.setRetryCount(0);
            job.setSumPage(count);
            job.setPageNo(i);
            jobs.add(job);
        }

        List<Producer> producers = getProducers();
        if(!CollectionUtils.isEmpty(producers)){
            //db为默认优先级最高的，会第一个执行调用，然后才会通过其他生产者进行通知
            producers.stream().forEach(producer -> producer.send(jobs));
        }


    }

}
